Proyecto final

IBM SkillsBuild Europa - Análisis de datos

Nombres y Apellidos: Wagner Roger, Nieto Cerna¶

Requisitos¶

  • Conocimientos de Python, Power BI o Tableau.
  • Comprensión de la limpieza de datos.
  • Comprensión de la visualización de datos.

Nivel de ejercicio: Intermedio¶

Duración: aproximadamente 3 horas¶

Análisis de datos de Airbnb:¶

Objetivo:¶

En este ejercicio, practicarás el análisis de datos sobre un conjunto de datos abiertos procedentes de Airbnb. Algunas de las tareas incluyen:

  • limpieza de datos,
  • transformación de datos y
  • visualización de datos.

Resumen sobre los datos de Airbnb:¶

Los criterios principales de la gente cuando visita lugares nuevos son contar con alojamiento y comida a precios razonables. Airbnb (Air-Bed-Breakfast) es un mercado en línea creado para satisfacer esta necesidad, pues permite a la gente alquilar sus casas durante plazos cortos. Estos servicios se ofrecen a un precio relativamente inferior al de los hoteles y en diversas ubicaciones geográficas. Además, personas de todo el mundo prefieren el servicio hogareño y económico.

Fuente de los datos¶

Puedes obtener el dataset para realizar este proyecto en el siguiente enlace: https://www.kaggle.com/datasets/arianazmoudeh/airbnbopendata

Este dataset contiene información sobre los alojamientos, tal como el barrio, el tipo de habitación, el precio, la disponibilidad, las opiniones, los gastos de servicio, la política de cancelación y las normas de uso de la casa.

¡Te deseamos lo mejor en tu análisis de los datos de Airbnb!

Tarea 1: Carga de datos (Python)¶

  1. Lee el fichero csv y cárgarlo en un dataframe de pandas.
  2. Visualiza las cinco primeras filas de tu dataframe.
  3. Visualize los tipos de datos de las columnas.

SOLUCIÓN¶

1. Lee el fichero csv y cárgarlo en un dataframe de pandas.¶

Para leer el fichero csv, primero identificamos la ruta o directorio de trabajo. El directorio de trabajo contiene el fichero csv. Hay dos formas de buscar la ruta o directorio de trabajo:

A) Forma 1¶

In [1]:
pwd
Out[1]:
'C:\\Users\\roger\\Desktop\\Final_Project'

B) Forma 2¶

In [2]:
import os
dir = os.getcwd()
dir
Out[2]:
'C:\\Users\\roger\\Desktop\\Final_Project'

Listar el directorio¶

Para listar el directorio utilizamos *listdir()*, esto nos muestra qué hay en nuestro directorio.

In [3]:
os.listdir(dir)
Out[3]:
['.ipynb_checkpoints', 'Airbnb_Open_Data.csv', 'Final_Project_Spanish.ipynb']

Nuestro directorio de trabajo contiene tres elementos: '.ipynb_checkpoints', 'Airbnb_Open_Data.csv', 'Final_Project_Spanish.ipynb'. Nuestro objetivo es leer el fichero 'Airbnb_Open_Data.csv'.

El fichero csv se lee utilizando *read_csv. Pero, primero necesitamos importar pandas* para cárgarlo en un dataframe de pandas. Tambíen necesitamos importar warnings para eliminar advertencias.

In [4]:
import pandas as pd
import warnings
warnings.filterwarnings(action="ignore")

Lectura del fichero csv.¶

In [5]:
df_Airbnb=pd.read_csv('Airbnb_Open_Data.csv')

Nuestro dataframe de pandas se llama "df_Airbnb"

2. Visualiza las cinco primeras filas de tu dataframe.¶

Para mostrar las primeras 5 filas de nuestro dataframe, utilizamos la función head().

In [6]:
df_Airbnb.head()
Out[6]:
id NAME host id host_identity_verified host name neighbourhood group neighbourhood lat long country ... service fee minimum nights number of reviews last review reviews per month review rate number calculated host listings count availability 365 house_rules license
0 1001254 Clean & quiet apt home by the park 80014485718 unconfirmed Madaline Brooklyn Kensington 40.64749 -73.97237 United States ... $193 10.0 9.0 10/19/2021 0.21 4.0 6.0 286.0 Clean up and treat the home the way you'd like... NaN
1 1002102 Skylit Midtown Castle 52335172823 verified Jenna Manhattan Midtown 40.75362 -73.98377 United States ... $28 30.0 45.0 5/21/2022 0.38 4.0 2.0 228.0 Pet friendly but please confirm with me if the... NaN
2 1002403 THE VILLAGE OF HARLEM....NEW YORK ! 78829239556 NaN Elise Manhattan Harlem 40.80902 -73.94190 United States ... $124 3.0 0.0 NaN NaN 5.0 1.0 352.0 I encourage you to use my kitchen, cooking and... NaN
3 1002755 NaN 85098326012 unconfirmed Garry Brooklyn Clinton Hill 40.68514 -73.95976 United States ... $74 30.0 270.0 7/5/2019 4.64 4.0 1.0 322.0 NaN NaN
4 1003689 Entire Apt: Spacious Studio/Loft by central park 92037596077 verified Lyndon Manhattan East Harlem 40.79851 -73.94399 United States ... $41 10.0 9.0 11/19/2018 0.10 3.0 1.0 289.0 Please no smoking in the house, porch or on th... NaN

5 rows × 26 columns

La visualización de las primeras 5 filas del dataframe, se hace para ver qué pinta tiene nuestro dataset. Podemos visualizar rápidamente que nuestro dataset contiene 26 columnas que incluye variables categóricas y númericas.

Contenido del dataset¶

El conjunto de datos utilizado en este proyecto consiste en información de Airbnb en Estados Unidos y abarca los siguientes parámetros:

  1. id = Identificador único de Airbnb para el anuncio.
  2. Name = Nombre del anuncio.
  3. host id = Identificador único de Airbnb para el anfitrión.
  4. host_identity_verified = Identidad del anfitrión.
  5. host name = Nombre del anfitrión. Generalmente, solo se incluye el nombre (o nombres).
  6. neighbourhood group = Grupo de barrios.
  7. neighbourhood = Barrio
  8. lat = Utiliza la proyección del Sistema Geodésico Mundial (WGS84) para la latitud.
  9. long = Utiliza la proyección del Sistema Geodésico Mundial (WGS84) para la longitud.
  10. country = País.
  11. country code = Código de país.
  12. Instant_bookable = Un indicador de listado comercial. Indica si el huésped puede reservar automáticamente el anuncio sin necesidad de que el anfitrión apruebe la solicitud de reserva.
  13. cancellation_policy = Política de cancelación.
  14. room type = Tipo de habitación. Los anfitriones de Airbnb pueden ofrecer casas/apartamentos enteros, habitaciones privadas, compartidas y, más recientemente, habitaciones de hotel. Dependiendo del tipo de habitación y la actividad, un anuncio residencial de Airbnb podría parecerse más a un hotel, perturbar a los vecinos, restar viviendas disponibles e incluso ser ilegal.
  15. Construction year = Año de construcción de la propiedad.
  16. price = Precio (costo de la habitación por noche).
  17. service fee = Tarifa de servicio.
  18. minimum nights = Noches mínimas (número mínimo de noches requeridas para reservar el anuncio).
  19. number of reviews = Número de revisiones (cantidad de revisiones que tiene el anuncio).
  20. last review = Última revisión (fecha de la última/más reciente revisión).
  21. reviews per month = Revisiones por mes (número de revisiones que ha recibido el anuncio a lo largo de su vida útil).
  22. review rate number = Número de tasa de revisión.
  23. calculated host listings count = Recuento calculado de fichas de anfitriones.
  24. availability 365 = Disponibilidad del anuncio en los próximos x días según lo determinado por el calendario.
  25. house_rules. Reglas de la casa.
  26. license = Número de licencia/permiso/registro.
In [7]:
import plotly.express as px
px.scatter_mapbox(df_Airbnb, lat="lat", lon="long", mapbox_style="open-street-map")

3. Visualize los tipos de datos de las columnas.¶

Hay distintas formas de mostrar los tipos de datos. Una de ellas es utilizando la función dtypes().

In [8]:
df_Airbnb.dtypes
Out[8]:
id                                  int64
NAME                               object
host id                             int64
host_identity_verified             object
host name                          object
neighbourhood group                object
neighbourhood                      object
lat                               float64
long                              float64
country                            object
country code                       object
instant_bookable                   object
cancellation_policy                object
room type                          object
Construction year                 float64
price                              object
service fee                        object
minimum nights                    float64
number of reviews                 float64
last review                        object
reviews per month                 float64
review rate number                float64
calculated host listings count    float64
availability 365                  float64
house_rules                        object
license                            object
dtype: object

El resultado arrojado nos muestra todas las variables que hay en nuestro dataset y de que tipos son éstas variables. Por ejemplo, tenemos float y object que representan a las variables numéricas contínuas y categóricas respectivamente. Otra forma de mostrar los tipos de datos es mediante la función info().

In [9]:
df_Airbnb.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 102599 entries, 0 to 102598
Data columns (total 26 columns):
 #   Column                          Non-Null Count   Dtype  
---  ------                          --------------   -----  
 0   id                              102599 non-null  int64  
 1   NAME                            102349 non-null  object 
 2   host id                         102599 non-null  int64  
 3   host_identity_verified          102310 non-null  object 
 4   host name                       102193 non-null  object 
 5   neighbourhood group             102570 non-null  object 
 6   neighbourhood                   102583 non-null  object 
 7   lat                             102591 non-null  float64
 8   long                            102591 non-null  float64
 9   country                         102067 non-null  object 
 10  country code                    102468 non-null  object 
 11  instant_bookable                102494 non-null  object 
 12  cancellation_policy             102523 non-null  object 
 13  room type                       102599 non-null  object 
 14  Construction year               102385 non-null  float64
 15  price                           102352 non-null  object 
 16  service fee                     102326 non-null  object 
 17  minimum nights                  102190 non-null  float64
 18  number of reviews               102416 non-null  float64
 19  last review                     86706 non-null   object 
 20  reviews per month               86720 non-null   float64
 21  review rate number              102273 non-null  float64
 22  calculated host listings count  102280 non-null  float64
 23  availability 365                102151 non-null  float64
 24  house_rules                     50468 non-null   object 
 25  license                         2 non-null       object 
dtypes: float64(9), int64(2), object(15)
memory usage: 20.4+ MB

La función info() nos muestra no sólo los tipos de datos sino también incluye la cantidad de no nulos, esta da más información que la función dtypes()

Tarea 2a: Limpieza de datos (cualquier herramienta)¶

  1. Elimina las columnas no deseadas del dataframe, entre ellas se incluyen host id, id, country y country code.
  2. Indica la razón por la cual se han eliminado estas columnas para tu análisis de datos.

Si utilizas Python para este ejercicio, incluye el código que hayas utilizado en las celdas siguientes. Si utilizas cualquier otra herramienta, incluye capturas de pantalla tomadas antes y después de eliminar las columnas.

SOLUCIÓN¶

1. Elimina las columnas no deseadas del dataframe, entre ellas se incluyen host id, id, country y country code.¶

Las columnas no deseadas son aquellas columnas que no aportan en nada para el análisis de datos. A continuación, se muestra las columnas no deseadas.

In [10]:
df_Airbnb[['host id','id','country','country code']]
Out[10]:
host id id country country code
0 80014485718 1001254 United States US
1 52335172823 1002102 United States US
2 78829239556 1002403 United States US
3 85098326012 1002755 United States US
4 92037596077 1003689 United States US
... ... ... ... ...
102594 12312296767 6092437 United States US
102595 77864383453 6092990 United States US
102596 69050334417 6093542 United States US
102597 11160591270 6094094 United States US
102598 68170633372 6094647 United States US

102599 rows × 4 columns

Las variables *country* y *country code*, son variables categóricas sin variabilidad, es decir, tienen una sola categoría.

In [11]:
df_Airbnb[['country']].value_counts()
Out[11]:
country      
United States    102067
dtype: int64
In [12]:
df_Airbnb[['country code']].value_counts()
Out[12]:
country code
US              102468
dtype: int64

Para eliminar las columnas no deseadas del dataframe aplicamos la función drop() y fijamos los parámetros de la función para cumplir con el objetivo. Para eliminar columnas (axis=1) y para las filas (axis=0). También fijamos inplace=True, para hacer cambios o reemplazar las manipulaciones realizadas en el dataframe, como por ejemplo, eliminar columnas.

In [13]:
df_Airbnb.drop(columns={'host id','id','country','country code'},axis=1,inplace=True) 

Comprobación¶

Para comprobar que nuestro dataframe ya no contiene las columnas no deseadas, mostramos las columnas.

In [14]:
df_Airbnb.columns
Out[14]:
Index(['NAME', 'host_identity_verified', 'host name', 'neighbourhood group',
       'neighbourhood', 'lat', 'long', 'instant_bookable',
       'cancellation_policy', 'room type', 'Construction year', 'price',
       'service fee', 'minimum nights', 'number of reviews', 'last review',
       'reviews per month', 'review rate number',
       'calculated host listings count', 'availability 365', 'house_rules',
       'license'],
      dtype='object')

Efectivamente, los resultados muestran que las columnas nos deseadas se han eliminado. En otras palabras, ya no aparecen en nuestro dataframe las columnas 'host id', 'id', 'country', 'country code'.

In [15]:
df_Airbnb.shape
Out[15]:
(102599, 22)

Después de eliminar las columnas no deseadas, nos quedamos con 22 columnas para hacer el análisis (inicialmente teníamos 26 columnas).

2. Indica la razón por la cual se han eliminado estas columnas para tu análisis de datos.¶

  • id: Identificador único de Airbnb para el anuncio, es un número de serie que no aportan en nada para el análisis de datos. Por lo tanto, eliminamos esta variable por ser irrelevante.

  • host id: Identificador único de Airbnb para el anfitrión, también es un número de serie que no aporta información significativa, es decir, no contribuye en nada para realizar el análisis de datos. Su presencia no es necesaria, por lo tanto, eliminamos para simplificar y limpiar los datos.

  • country: País, es una variable categórica sin variabilidad, es decir, que tiene solo una categoría (es constante en todos los casos). No aporta información significativa para el análisis de datos, por lo tanto, se elimina esta variable.

  • country code: Código de país, es otra variable categórica que no aporta en nada porque tiene solo una categoría, por lo tanto, se elimina esta variable para realizar el análisis de datos.

Tarea 2b: Limpieza de datos (Python)¶

  • Compueba si hay valores nulos y muestra el recuento en orden ascendente. Si faltan valores, imputa los valores como consideres.
  • Comprueba si hay valores duplicados y elimínalos.
  • Muestra el número total de registros antes y después de eliminar los duplicados.

SOLUCIÓN¶

En análisis de datos, generalmente no es bueno eliminar datos. Es mejor rellenar valores nulos con la media, mediana, o la moda.

Compueba si hay valores nulos y muestra el recuento en orden ascendente. Si faltan valores, imputa los valores como consideres¶

In [16]:
## Comprueba si hay valores nulos.
df_Airbnb.isnull().head()
Out[16]:
NAME host_identity_verified host name neighbourhood group neighbourhood lat long instant_bookable cancellation_policy room type ... service fee minimum nights number of reviews last review reviews per month review rate number calculated host listings count availability 365 house_rules license
0 False False False False False False False False False False ... False False False False False False False False False True
1 False False False False False False False False False False ... False False False False False False False False False True
2 False True False False False False False False False False ... False False False True True False False False False True
3 True False False False False False False False False False ... False False False False False False False False True True
4 False False False False False False False False False False ... False False False False False False False False False True

5 rows × 22 columns

Si hay valores nulos (por ejemplo, la columna NAME del registro 3): los True representan valores nulos y los False representan los no nulos.

In [17]:
# Ver los nulos por columnas
df_Airbnb[df_Airbnb['lat'].isnull()]
Out[17]:
NAME host_identity_verified host name neighbourhood group neighbourhood lat long instant_bookable cancellation_policy room type ... service fee minimum nights number of reviews last review reviews per month review rate number calculated host listings count availability 365 house_rules license
779 Large, furnished room in a 2 bedroom! unconfirmed Gibson Brooklyn Crown Heights NaN NaN False strict Private room ... $108 1.0 1.0 3/18/2017 0.04 2.0 1.0 41.0 - Weekly and monthly prices are much lower - P... NaN
785 Authentic NY Charming Artist Loft unconfirmed Bailey Brooklyn Greenpoint NaN NaN False strict Entire home/apt ... $212 5.0 14.0 6/19/2019 0.16 5.0 1.0 226.0 We live and let live - hoping that you'd be re... NaN
799 Huge room with private balcony verified Hunt Manhattan East Village NaN NaN False flexible Private room ... $101 6.0 1.0 5/6/2013 0.01 1.0 1.0 240.0 Expect respect for the family and the space--t... NaN
814 Decorators 5-Star Flat West Village verified Watson Manhattan West Village NaN NaN True strict Entire home/apt ... $76 20.0 157.0 8/11/2016 1.71 4.0 1.0 61.0 Please keep it clean, thats all we really ask ... NaN
843 Nice Private Room Beauty in Queens verified Roberts Queens Elmhurst NaN NaN True strict Private room ... $45 1.0 63.0 5/18/2019 0.89 3.0 2.0 70.0 NaN NaN
885 Cute Room in Historic Loft! unconfirmed Jones Brooklyn Greenpoint NaN NaN True flexible Private room ... $105 14.0 22.0 5/2/2019 0.25 1.0 1.0 266.0 Pets are cool (just clean up after them!), smo... NaN
926 21 day Chelsea Apartment rental unconfirmed Owens Manhattan Flatiron District NaN NaN False strict Private room ... $125 21.0 0.0 NaN NaN 2.0 1.0 104.0 NaN NaN
986 New York City for All Seasons! unconfirmed Douglas Manhattan Upper West Side NaN NaN True flexible Private room ... $83 1.0 25.0 6/22/2013 0.28 2.0 1.0 259.0 No Smoking No Pets NaN

8 rows × 22 columns

El resultado nos muestra 8 valores nulos para latitud representados por "NaN".

In [18]:
# Muestra el recuento de valores nulos
df_Airbnb.isnull().sum()
Out[18]:
NAME                                 250
host_identity_verified               289
host name                            406
neighbourhood group                   29
neighbourhood                         16
lat                                    8
long                                   8
instant_bookable                     105
cancellation_policy                   76
room type                              0
Construction year                    214
price                                247
service fee                          273
minimum nights                       409
number of reviews                    183
last review                        15893
reviews per month                  15879
review rate number                   326
calculated host listings count       319
availability 365                     448
house_rules                        52131
license                           102597
dtype: int64

Hay muchos nulos, están feas las columnas. ¿Qué podemos hacer con esos nulos?. Podemos ordenar de forma ascedente para ver que columna tiene mas nulos.

In [19]:
#Muestra el recuento de valores nulos en orden ascendente
df_Airbnb.isnull().sum().sort_values(ascending=True)
Out[19]:
room type                              0
lat                                    8
long                                   8
neighbourhood                         16
neighbourhood group                   29
cancellation_policy                   76
instant_bookable                     105
number of reviews                    183
Construction year                    214
price                                247
NAME                                 250
service fee                          273
host_identity_verified               289
calculated host listings count       319
review rate number                   326
host name                            406
minimum nights                       409
availability 365                     448
reviews per month                  15879
last review                        15893
house_rules                        52131
license                           102597
dtype: int64

El resultado muestra que todas las columnas tienen valores nulos, excepto la columna tipo de habitaciones "room type".

Inputación de los valores nulos o faltantes¶

Inputamos los valores nulos de las variables categoricas con la moda y de las variables continuas con la media o mediana. La mediana se puede utilizar cuando se tiene variables con valores extremos. Se puede ordenar los valores de menor a mayor y obtener la mediana para rellenar los valor nulos.

In [20]:
# Cálculo de la media 
df_Airbnb['lat'].mean()
Out[20]:
40.72809387037124
In [21]:
# Cálculo de la moda (el valor más repetido para una variable categórica)
df_Airbnb['neighbourhood'].mode()
Out[21]:
0    Bedford-Stuyvesant
dtype: object
In [22]:
df_Airbnb['neighbourhood'].mode()[0]
Out[22]:
'Bedford-Stuyvesant'

Inputación de los valores faltantes por la moda (para columnas categóricas)¶

In [23]:
# Frecuencia de varios para extraer la moda 
df_Airbnb['neighbourhood'].groupby(df_Airbnb['neighbourhood']).count().sort_values(ascending=False)
Out[23]:
neighbourhood
Bedford-Stuyvesant        7937
Williamsburg              7775
Harlem                    5466
Bushwick                  4982
Hell's Kitchen            3965
                          ... 
Woodrow                      3
Gerritsen Beach              3
Fort Wadsworth               2
Glen Oaks                    2
Chelsea, Staten Island       1
Name: neighbourhood, Length: 224, dtype: int64

La moda es la que más veces se repite, en este caso la moda es el barrio que más se repite y se llama Bedford-Stuyvesant.

In [24]:
# Valores nulos para la columna 'neighbourhood'
df_Airbnb['neighbourhood'].isnull().sum()
Out[24]:
16
In [25]:
#Inputación de los valores nulos por la moda
df_Airbnb['neighbourhood'].fillna(df_Airbnb['neighbourhood'].mode()[0],inplace=True)
In [26]:
df_Airbnb['neighbourhood'].isnull().sum()
Out[26]:
0

Ya no tenemos valores nulos, se ha reemplazado los 16 valores nulos de la columna 'neighbourhood' por la moda Bedford-Stuyvesant.

Inputación de los valores faltantes por la media o mediana (para columnas númericas)¶

In [27]:
# Valores nulos para la columna 'lat'
df_Airbnb['lat'].isnull().sum()
Out[27]:
8
In [28]:
# Inputación de los valores nulos por la media
df_Airbnb['lat'].fillna(df_Airbnb['lat'].mean(),inplace=True)
In [29]:
# Comprobar que ya no hay valores nulos en la columna 'lat'
df_Airbnb['lat'].isnull().sum()
Out[29]:
0

A continuación hacemos la inputación de manera masiva, ya que, inputar columna por columna no es buena idea en análisis de datos.

Inputación Masiva¶

In [30]:
for col in df_Airbnb.columns:
    if (df_Airbnb[col].dtype == 'O'):
        print("Rellenando valores nulos en la columna categórica:", col)
        df_Airbnb[col].fillna(df_Airbnb[col].mode()[0],inplace=True)
    
    else:
        print("Rellenando valores nulos en la columna numérica:", col)
        df_Airbnb[col].fillna(df_Airbnb[col].mean(),inplace=True)
Rellenando valores nulos en la columna categórica: NAME
Rellenando valores nulos en la columna categórica: host_identity_verified
Rellenando valores nulos en la columna categórica: host name
Rellenando valores nulos en la columna categórica: neighbourhood group
Rellenando valores nulos en la columna categórica: neighbourhood
Rellenando valores nulos en la columna numérica: lat
Rellenando valores nulos en la columna numérica: long
Rellenando valores nulos en la columna categórica: instant_bookable
Rellenando valores nulos en la columna categórica: cancellation_policy
Rellenando valores nulos en la columna categórica: room type
Rellenando valores nulos en la columna numérica: Construction year
Rellenando valores nulos en la columna categórica: price
Rellenando valores nulos en la columna categórica: service fee
Rellenando valores nulos en la columna numérica: minimum nights
Rellenando valores nulos en la columna numérica: number of reviews
Rellenando valores nulos en la columna categórica: last review
Rellenando valores nulos en la columna numérica: reviews per month
Rellenando valores nulos en la columna numérica: review rate number
Rellenando valores nulos en la columna numérica: calculated host listings count
Rellenando valores nulos en la columna numérica: availability 365
Rellenando valores nulos en la columna categórica: house_rules
Rellenando valores nulos en la columna categórica: license
In [31]:
# Número total de registro después de la inputacón de los valores nulos.
df_Airbnb.shape
Out[31]:
(102599, 22)
In [32]:
df_Airbnb.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 102599 entries, 0 to 102598
Data columns (total 22 columns):
 #   Column                          Non-Null Count   Dtype  
---  ------                          --------------   -----  
 0   NAME                            102599 non-null  object 
 1   host_identity_verified          102599 non-null  object 
 2   host name                       102599 non-null  object 
 3   neighbourhood group             102599 non-null  object 
 4   neighbourhood                   102599 non-null  object 
 5   lat                             102599 non-null  float64
 6   long                            102599 non-null  float64
 7   instant_bookable                102599 non-null  bool   
 8   cancellation_policy             102599 non-null  object 
 9   room type                       102599 non-null  object 
 10  Construction year               102599 non-null  float64
 11  price                           102599 non-null  object 
 12  service fee                     102599 non-null  object 
 13  minimum nights                  102599 non-null  float64
 14  number of reviews               102599 non-null  float64
 15  last review                     102599 non-null  object 
 16  reviews per month               102599 non-null  float64
 17  review rate number              102599 non-null  float64
 18  calculated host listings count  102599 non-null  float64
 19  availability 365                102599 non-null  float64
 20  house_rules                     102599 non-null  object 
 21  license                         102599 non-null  object 
dtypes: bool(1), float64(9), object(12)
memory usage: 16.5+ MB

Ya no tenemos valores nulos, ahora todas tienen el tamaño del dataframe.

In [33]:
# Muestra el tamaño del dataframe
df_Airbnb.shape
Out[33]:
(102599, 22)
In [34]:
# Muestra que el dataframe ya no tiene valores nulos o faltantes 
df_Airbnb.isnull().sum()
Out[34]:
NAME                              0
host_identity_verified            0
host name                         0
neighbourhood group               0
neighbourhood                     0
lat                               0
long                              0
instant_bookable                  0
cancellation_policy               0
room type                         0
Construction year                 0
price                             0
service fee                       0
minimum nights                    0
number of reviews                 0
last review                       0
reviews per month                 0
review rate number                0
calculated host listings count    0
availability 365                  0
house_rules                       0
license                           0
dtype: int64

Comprueba si hay valores duplicados y elimínalos.¶

In [35]:
## Comprueba si hay valores duplicados.
df_Airbnb.duplicated().sum()
Out[35]:
3453

Tenemos 3453 duplicados. En análisis de datos cualquier duplicado se elimina.

In [36]:
# Elimina los valores duplicados
df_Airbnb.drop_duplicates(inplace=True)
In [37]:
# Muestre que el dataframe ya no tiene duplicados
df_Airbnb.duplicated().sum()
Out[37]:
0

Efectivamente, ya no tenemos duplicados.

Muestra el número total de registros antes y después de eliminar los duplicados.¶

In [38]:
# Número total de registro antes de eliminar los duplicados
# df_Airbnb.shape
# (102599, 22)
In [39]:
# Número total de registros después de eliminar los duplicados
df_Airbnb.shape
Out[39]:
(99146, 22)

El número total de registros antes de eliminar los duplicados es de 102.599, y después de eliminar los duplicados es de 99.146

Tarea 3: Transformación de datos (cualquier herramienta)¶

  • Cambia el nombre de la columna availability 365 a days_booked.
  • Convierte todos los nombres de columna a minúsculas y sustituye los espacios en los nombres de columna por un guión bajo "_".
  • Elimina el signo de dólares y la coma de las columnas price y service_fee. Si es necesario, convierte estas dos columnas al tipo de datos adecuado.

Si utilizas Python para este ejercicio, incluye el código que hayas utilizado en las celdas siguientes. Si utilizas cualquier otra herramienta, incluye capturas de pantalla de tu trabajo.

SOLUCIÓN¶

In [40]:
df_Airbnb.columns
Out[40]:
Index(['NAME', 'host_identity_verified', 'host name', 'neighbourhood group',
       'neighbourhood', 'lat', 'long', 'instant_bookable',
       'cancellation_policy', 'room type', 'Construction year', 'price',
       'service fee', 'minimum nights', 'number of reviews', 'last review',
       'reviews per month', 'review rate number',
       'calculated host listings count', 'availability 365', 'house_rules',
       'license'],
      dtype='object')

Cambia el nombre de la columna availability 365 a days_booked.¶

In [41]:
## Cambia el nombre de la columna.
df_Airbnb.rename(columns={'availability 365': 'days_booked'},inplace=True)
In [42]:
df_Airbnb.columns
Out[42]:
Index(['NAME', 'host_identity_verified', 'host name', 'neighbourhood group',
       'neighbourhood', 'lat', 'long', 'instant_bookable',
       'cancellation_policy', 'room type', 'Construction year', 'price',
       'service fee', 'minimum nights', 'number of reviews', 'last review',
       'reviews per month', 'review rate number',
       'calculated host listings count', 'days_booked', 'house_rules',
       'license'],
      dtype='object')

Convierte todos los nombres de columna a minúsculas y sustituye los espacios en los nombres de columna por un guión bajo "_".¶

In [43]:
## Convierte todos los nombres de columna a minúsculas y sustituye los espacios por un guión bajo "_".
df_Airbnb.columns = [col.lower().replace(" ","_") for col in df_Airbnb.columns]
df_Airbnb.columns
Out[43]:
Index(['name', 'host_identity_verified', 'host_name', 'neighbourhood_group',
       'neighbourhood', 'lat', 'long', 'instant_bookable',
       'cancellation_policy', 'room_type', 'construction_year', 'price',
       'service_fee', 'minimum_nights', 'number_of_reviews', 'last_review',
       'reviews_per_month', 'review_rate_number',
       'calculated_host_listings_count', 'days_booked', 'house_rules',
       'license'],
      dtype='object')

Elimina el signo de dólares y la coma de las columnas price y service_fee. Si es necesario, convierte estas dos columnas al tipo de datos adecuado.¶

In [44]:
## Elimina el signo de dólares y la coma de las columnas. 
# Si es necesario, convierte estas dos columnas al tipo de datos adecuado.
df_Airbnb['price']
Out[44]:
0           $966 
1           $142 
2           $620 
3           $368 
4           $204 
           ...   
102053      $696 
102054      $909 
102055      $387 
102056      $848 
102057    $1,128 
Name: price, Length: 99146, dtype: object
In [45]:
df_Airbnb['service_fee']
Out[45]:
0         $193 
1          $28 
2         $124 
3          $74 
4          $41 
          ...  
102053     $41 
102054     $41 
102055     $41 
102056     $41 
102057     $41 
Name: service_fee, Length: 99146, dtype: object

Definimos una función para eliminar el signo de dólares y la coma¶

In [46]:
def eliminar_dolar_coma(value):
    if pd.isna(value):
        return np.NaN
    else:
        return float(value.replace("$","").replace(",",""))
In [47]:
# Aplicamos la función a la columna 'price' utilizando apply
df_Airbnb['price'] = df_Airbnb['price'].apply(eliminar_dolar_coma)
df_Airbnb['price']
Out[47]:
0          966.0
1          142.0
2          620.0
3          368.0
4          204.0
           ...  
102053     696.0
102054     909.0
102055     387.0
102056     848.0
102057    1128.0
Name: price, Length: 99146, dtype: float64

apply aplica a toda una columna

In [48]:
# Aplicamos la función a la columna 'service_fee' utilizando apply
df_Airbnb['service_fee'] = df_Airbnb['service_fee'].apply(lambda x: eliminar_dolar_coma(x))
df_Airbnb['service_fee']
Out[48]:
0         193.0
1          28.0
2         124.0
3          74.0
4          41.0
          ...  
102053     41.0
102054     41.0
102055     41.0
102056     41.0
102057     41.0
Name: service_fee, Length: 99146, dtype: float64

Tarea 4: Análisis exploratorio de datos (cualquier herramienta)¶

  • Enumera los tipos de habitaciones disponibles en el dataset.
  • ¿Qué tipo de habitación tiene la política de cancelación más estricta?
  • Enumera el precio medio por barrio y señala cuál es el conjunto de barrios más caro para alquilar.

Si utilizas Python para este ejercicio, incluye el código que hayas utilizado en las celdas siguientes. Si utilizas cualquier otra herramienta, incluye capturas de pantalla de tu trabajo.

SOLUCIÓN¶

Enumera los tipos de habitaciones disponibles en el dataset.¶

In [49]:
## Enumera los tipos de habitaciones disponibles en Airbnb.
df_Airbnb['room_type'].value_counts()
Out[49]:
Entire home/apt    51995
Private room       44887
Shared room         2149
Hotel room           115
Name: room_type, dtype: int64

¿Qué tipo de habitación tiene la política de cancelación más estricta?¶

In [50]:
## Dataframe filtrado por una condición 'strict'
df_PCE=df_Airbnb[df_Airbnb['cancellation_policy'] == 'strict']
df_PCE.head(2)
Out[50]:
name host_identity_verified host_name neighbourhood_group neighbourhood lat long instant_bookable cancellation_policy room_type ... service_fee minimum_nights number_of_reviews last_review reviews_per_month review_rate_number calculated_host_listings_count days_booked house_rules license
0 Clean & quiet apt home by the park unconfirmed Madaline Brooklyn Kensington 40.64749 -73.97237 False strict Private room ... 193.0 10.0 9.0 10/19/2021 0.21 4.0 6.0 286.0 Clean up and treat the home the way you'd like... 41662/AL
8 Large Furnished Room Near B'way verified Evelyn Manhattan Hell's Kitchen 40.76489 -73.98493 True strict Private room ... 204.0 2.0 430.0 6/24/2019 3.47 3.0 1.0 180.0 - Please clean up after yourself when using th... 41662/AL

2 rows × 22 columns

In [51]:
# Muestre tipos de habitación con una política de cancelación más estrcita
resultado=df_PCE[['room_type']].value_counts().sort_values(ascending=False).reset_index().rename(columns={0:'política_cancelación_estricta'})
resultado
Out[51]:
room_type política_cancelación_estricta
0 Entire home/apt 17239
1 Private room 14936
2 Shared room 718
3 Hotel room 34

El tipo de habitación que tiene una política de cancelación más estricta es toda la casa.

Enumera los precios por barrio y menciona también cuál es el grupo de barrios con alquileres más caros¶

Primero limpiamos la columna 'neighbourhood_group'. Los nombres del grupo de barrios de la ciudad de Nueva York, algunos de ellos tienen errores tipográficos.

  • Brooklyn (corregido de "brookln")
  • Manhattan (corregido de "manhatan")
In [52]:
# Corregir errores tipográficos en la columna "neighbourhood_group"

df_Airbnb['neighbourhood_group'] = df_Airbnb['neighbourhood_group'].replace({'brookln': 'Brooklyn', 'manhatan': 'Manhattan'}, 
                                   regex=True, inplace=False)
In [53]:
# Método 1
## Enumera los precios por barrio y menciona también cuál es el grupo de barrios con alquileres más caros
df_PB=df_Airbnb['price'].groupby(df_Airbnb['neighbourhood_group']).mean().sort_values(ascending=False)
df_PB
Out[53]:
neighbourhood_group
Queens           628.668822
Brooklyn         625.450801
Bronx            625.271511
Staten Island    625.060870
Manhattan        621.637624
Name: price, dtype: float64
In [54]:
# Método 2
## Enumera los precios por barrio y menciona también cuál es el grupo de barrios con alquileres más caros
df_PreciosxBarrio=df_Airbnb.groupby('neighbourhood_group').price.mean().sort_values(ascending=False).reset_index(level='neighbourhood_group')
df_PreciosxBarrio
Out[54]:
neighbourhood_group price
0 Queens 628.668822
1 Brooklyn 625.450801
2 Bronx 625.271511
3 Staten Island 625.060870
4 Manhattan 621.637624

Tarea 5a: Visualización de datos (Cualquier herramienta)¶

  • Enumerar los distintos tipos de habitaciones disponibles en Airnb
  • Qué tipo de habitación se adhiere a una política de cancelación más estricta.
  • Enumere los precios por grupo de barrios y mencione también cuál es el grupo de barrios más caro para los alquileres.
  • Enumere los 10 barrios más caros por orden creciente de precio con la ayuda de un gráfico de barras horizontales. ¿Cuál es el barrio más barato?
  • Enumere los barrios que ofrecen alquileres a corto plazo de menos de 10 días. Ilustrar con un gráfico de barras
  • Enumere los precios con respecto al tipo de habitación utilizando un gráfico de barras y exponga también sus inferencias.
  • Cree un gráfico circular que muestre la distribución de los días reservados para cada grupo de barrios.

Si utiliza Python para este ejercicio, por favor incluya el código en las celdas de abajo. Si utiliza cualquier otra herramienta, por favor incluya pantallazos de su trabajo.

SOLUCIÓN¶

Enumerar los distintos tipos de habitaciones disponibles en Airbnb¶

In [55]:
# Tipos de habitaciones disponibles en Airbnb
df_barras=df_Airbnb[['room_type']].value_counts().sort_values(ascending=False).reset_index().rename(columns={0:'cantidad'})
df_barras
Out[55]:
room_type cantidad
0 Entire home/apt 51995
1 Private room 44887
2 Shared room 2149
3 Hotel room 115
In [56]:
# Gráfico de barras 1
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(15, 8))
bars=ax.bar(df_barras['room_type'], df_barras['cantidad'], color='brown') #barh

# Añadir etiquetas y título
plt.xlabel('Tipos de Habitaciones',fontsize=20)
plt.ylabel('Número de Habitaciones',fontsize=20)
plt.title('Tipos de Habitaciones en Airbnb',fontsize=20)

# Añadir los valores encima de las barras
for bar in bars:
    yval = bar.get_height()
    plt.text(bar.get_x() + bar.get_width()/2, yval + 0.1, round(yval, 1), ha='center', va='bottom',fontsize=20)


# Mostrar el gráfico
plt.show()

Al examinar el gráfico, se observa que el tipo de habitación con la mayor disponibilidad en Airbnb es toda la casa, mientras que el tipo de habitación con la menor disponibilidad es la habitación de hotel.

Qué tipo de habitación se adhiere a una política de cancelación más estricta.¶

In [57]:
# Conjunto de datos con la condición: política de cancelación estricta
dat=df_Airbnb[df_Airbnb['cancellation_policy'] == 'strict']
dat.head(2)
Out[57]:
name host_identity_verified host_name neighbourhood_group neighbourhood lat long instant_bookable cancellation_policy room_type ... service_fee minimum_nights number_of_reviews last_review reviews_per_month review_rate_number calculated_host_listings_count days_booked house_rules license
0 Clean & quiet apt home by the park unconfirmed Madaline Brooklyn Kensington 40.64749 -73.97237 False strict Private room ... 193.0 10.0 9.0 10/19/2021 0.21 4.0 6.0 286.0 Clean up and treat the home the way you'd like... 41662/AL
8 Large Furnished Room Near B'way verified Evelyn Manhattan Hell's Kitchen 40.76489 -73.98493 True strict Private room ... 204.0 2.0 430.0 6/24/2019 3.47 3.0 1.0 180.0 - Please clean up after yourself when using th... 41662/AL

2 rows × 22 columns

In [58]:
# Frecuencia de tipos de habitación con la política de cancelación estrcita
df_pce=dat[['room_type']].value_counts().sort_values(ascending=False).reset_index().rename(columns={0:'Cantidad'})
df_pce
Out[58]:
room_type Cantidad
0 Entire home/apt 17239
1 Private room 14936
2 Shared room 718
3 Hotel room 34
In [59]:
# Gráfico de barras 1
fig, ax = plt.subplots(figsize=(15, 8))
bars = ax.bar(df_pce['room_type'], df_pce['Cantidad'], color='purple') 

plt.xlabel('Tipos de Habitaciones con una Política de Cancelación Estricta',fontsize=15)
plt.ylabel('Número de Habitaciones',fontsize=15)
plt.title('Frecuencia de Tipos de Habitaciones con una Política de Cancelación Estricta en Airbnb',fontsize=15)

# Añadir los valores encima de las barras
for bar in bars:
    yval = bar.get_height()
    plt.text(bar.get_x() + bar.get_width()/2, yval + 0.1, round(yval, 1), ha='center', va='bottom',fontsize=20)


# Mostrar el gráfico
plt.show()

En el gráfico, se destaca que hay más habitaciones privadas con la política de cancelación más estricta, y menos habitaciones de hotel con política de cancelación más estricta."

Enumere los precios por grupo de barrios y mencione también cuál es el grupo de barrios más caro para los alquileres.¶

In [60]:
df_Airbnb[['price','neighbourhood_group']]
Out[60]:
price neighbourhood_group
0 966.0 Brooklyn
1 142.0 Manhattan
2 620.0 Manhattan
3 368.0 Brooklyn
4 204.0 Manhattan
... ... ...
102053 696.0 Brooklyn
102054 909.0 Brooklyn
102055 387.0 Brooklyn
102056 848.0 Manhattan
102057 1128.0 Manhattan

99146 rows × 2 columns

In [61]:
df_Airbnb['price'].groupby(df_Airbnb['neighbourhood_group']).mean().sort_values(ascending=False)
Out[61]:
neighbourhood_group
Queens           628.668822
Brooklyn         625.450801
Bronx            625.271511
Staten Island    625.060870
Manhattan        621.637624
Name: price, dtype: float64
In [62]:
# Precio medio por grupo de barrios
df_preciosGB=round(df_Airbnb.groupby('neighbourhood_group').price.mean(),2).sort_values(ascending=False).reset_index(level='neighbourhood_group')
df_preciosGB
Out[62]:
neighbourhood_group price
0 Queens 628.67
1 Brooklyn 625.45
2 Bronx 625.27
3 Staten Island 625.06
4 Manhattan 621.64
In [63]:
# Gráfico de barras 
fig, ax = plt.subplots(figsize=(15,8))
bars = ax.bar(df_preciosGB['neighbourhood_group'], df_preciosGB['price'], color='green')

# Añadir etiquetas y título
plt.xlabel('Grupo de barrios',fontsize=20)
plt.ylabel('Precio medio [$]',fontsize=20)
plt.title('Precio medio de alquiler por grupo de barrios', fontsize=20)

# Añadir etiquetas de dólares encima de las barras
for bar in bars:
    yval = bar.get_height()
    ax.annotate(f'${yval:.2f}', (bar.get_x() + bar.get_width() / 2., yval),
                ha='center', va='center', xytext=(0, 10), textcoords='offset points', fontsize=12, color='black')

# Mostrar el gráfico
plt.show()

Observando el gráfico, el grupo de barrios más caro para alquileres es Queens, seguido por Brooklyn, Bronx, ... Mientras que el grupo de barrios menos caro para alquileres es Manhattan. Es importante señalar, que no hay una diferencia significativa en el precio medio de alquileres.

Enumere los 10 barrios más caros por orden creciente de precio con la ayuda de un gráfico de barras horizontales. ¿Cuál es el barrio más barato?¶

In [64]:
df_Airbnb[['neighbourhood','price']]
Out[64]:
neighbourhood price
0 Kensington 966.0
1 Midtown 142.0
2 Harlem 620.0
3 Clinton Hill 368.0
4 East Harlem 204.0
... ... ...
102053 Flatbush 696.0
102054 Bushwick 909.0
102055 Bedford-Stuyvesant 387.0
102056 Harlem 848.0
102057 Harlem 1128.0

99146 rows × 2 columns

Rankin de los 10 barrios más caros¶

In [65]:
df_pre=round(df_Airbnb.groupby('neighbourhood').price.mean(),2).sort_values(ascending=True).reset_index(level='neighbourhood').head(10)
df_pre
Out[65]:
neighbourhood price
0 Lighthouse Hill 107.67
1 Bay Terrace, Staten Island 306.00
2 Spuyten Duyvil 307.00
3 Breezy Point 309.89
4 Rossville 327.50
5 Richmondtown 373.40
6 Castleton Corners 417.23
7 Emerson Hill 443.80
8 West Farms 463.17
9 Oakwood 469.31
In [66]:
# Gráfico de barras 1
df_pre.plot(kind='barh',x='neighbourhood',y='price',figsize=(15,8), color='Red')

plt.xlabel('Precio Medio de Alquiler [$]',fontsize=15)
plt.ylabel('Barrio',fontsize=15)
plt.title('Precio Medio de Alquiler de los 10 Barrios más Caros', fontsize=15)
plt.show()

En el gráfico, Lighthouse Hill es el barrio más asequible entre los 10 más caros.

Enumere los barrios que ofrecen alquileres a corto plazo de menos de 10 días. Ilustrar con un gráfico de barras¶

minimum_nights =Número mínimo de noches de estancia para el anuncio

1. Barrios que ofrecen alquileres a corto plazo (Ranking de los 20 más frecuentes)¶

In [67]:
# Filtrar alquileres a corto plazo (menos de 10 días)
alquileres_corto_plazo = df_Airbnb[df_Airbnb['minimum_nights'] < 10]

# Contar la frecuencia de cada barrio en alquileres a corto plazo
frecuencia_barrios = alquileres_corto_plazo['neighbourhood'].value_counts().head(20).sort_values(ascending=True)

# Mostrar los barrios que ofrecen alquileres a corto plazo de menos de 10 días
print("Barrios que ofrecen alquileres a corto plazo de menos de 10 días:")
print(frecuencia_barrios)
Barrios que ofrecen alquileres a corto plazo de menos de 10 días:
East Flatbush          972
Financial District    1036
Flatbush              1090
West Village          1137
Washington Heights    1494
Astoria               1545
Lower East Side       1574
Chelsea               1726
Greenpoint            1726
East Harlem           1900
Midtown               2380
Upper East Side       2444
Upper West Side       2730
Crown Heights         2732
East Village          2843
Hell's Kitchen        2879
Bushwick              4083
Harlem                4447
Williamsburg          6342
Bedford-Stuyvesant    6552
Name: neighbourhood, dtype: int64
In [68]:
# Gráfico de barras 
import pandas as pd
import matplotlib.pyplot as plt

frecuencia_barrios.plot(kind='barh', figsize=(15, 10), color='purple')

plt.title('Frecuencia de Alquileres a Corto Plazo (menos de 10 días) por Barrio',fontsize=15)
plt.ylabel('Barrio',fontsize=15)
plt.xlabel('Número de Alquileres',fontsize=15)

plt.show()

Bedford-Stuyvesant y Williamsburg son los barrios que ofrecen más alquileres a corto plazo (menos de 10 días), mientras que East Flatbush ofrece menos alquileres de corta duración entre los 20 barrios más frecuentes.

2. Grupo de barrios que ofrecen alquileres a corto plazo¶

In [69]:
# Filtrar alquileres a corto plazo (menos de 10 días)
alquileres_cortoPlazo = df_Airbnb[df_Airbnb['minimum_nights'] < 10]

# Contar la frecuencia de cada barrio en alquileres a corto plazo
frecuencia_grupo_barrios = alquileres_cortoPlazo['neighbourhood_group'].value_counts(ascending=True)

# Mostrar los barrios que ofrecen alquileres a corto plazo de menos de 10 días
print("Grupo de barrios que ofrecen alquileres a corto plazo de menos de 10 días:")
print(frecuencia_grupo_barrios)
Grupo de barrios que ofrecen alquileres a corto plazo de menos de 10 días:
Staten Island      829
Bronx             2367
Queens           10970
Manhattan        32793
Brooklyn         34346
Name: neighbourhood_group, dtype: int64
In [70]:
# Gráfico de barras
import pandas as pd
import matplotlib.pyplot as plt

frecuencia_grupo_barrios.plot(kind='barh', figsize=(15, 6), color='blue')

plt.title('Frecuencia de Alquileres a Corto Plazo (menos de 10 días) por Grupo de Barrio',fontsize=15)
plt.xlabel('Grupo de Barrios',fontsize=15)
plt.ylabel('Número de Alquileres',fontsize=15)

plt.show()

Brooklyn y Manhattan ofrecen más alquileres a corto plazo (menos de 10 días), mientras que Staten Island ofrece menos alquileres de corta duración.

Enumere los precios con respecto al tipo de habitación utilizando un gráfico de barras y exponga también sus inferencias.¶

In [71]:
df_Airbnb[['price','room_type']]
Out[71]:
price room_type
0 966.0 Private room
1 142.0 Entire home/apt
2 620.0 Private room
3 368.0 Entire home/apt
4 204.0 Entire home/apt
... ... ...
102053 696.0 Private room
102054 909.0 Private room
102055 387.0 Entire home/apt
102056 848.0 Private room
102057 1128.0 Entire home/apt

99146 rows × 2 columns

In [72]:
# Precio medio con respecto al tipo de habitación
df_precioRoom=df_Airbnb.groupby('room_type').price.mean().sort_values(ascending=True).reset_index(level='room_type')
df_precioRoom
Out[72]:
room_type price
0 Private room 623.842516
1 Entire home/apt 624.192095
2 Shared room 630.912517
3 Hotel room 666.391304
In [73]:
# Gráfico de barras 1
fig, ax = plt.subplots(figsize=(15,8))
bars = ax.bar(df_precioRoom['room_type'], df_precioRoom['price'], color='red')

# Añadir etiquetas y título
plt.xlabel('Tipo de habitación',fontsize=15)
plt.ylabel('Precio medio [$]',fontsize=15)
plt.title('Precio medio por tipo de habitación', fontsize=15)

# Añadir etiquetas de dólares encima de las barras
for bar in bars:
    yval = bar.get_height()
    ax.annotate(f'${yval:.2f}', (bar.get_x() + bar.get_width() / 2., yval),
                ha='center', va='center', xytext=(0, 10), textcoords='offset points', fontsize=15, color='black')

# Mostrar el gráfico
plt.show()

En promedio, las habitaciones del hotel presentan los precios más elevados, mientras que las habitaciones privadas son las más asequibles. No obstante, la diferencia en el precio medio entre las habitaciones privadas, las habitaciones compartidas y la opción de alquilar toda la casa no muestra significancia estadística."

Cree un gráfico circular que muestre la distribución de los días reservados para cada grupo de barrios.¶

In [74]:
# Distribución de los días reservados para cada grupo de barrios
df_DR=df_Airbnb.groupby('neighbourhood_group').days_booked.mean().sort_values(ascending=False).reset_index(level='neighbourhood_group')
df_DR
Out[74]:
neighbourhood_group days_booked
0 Staten Island 196.038188
1 Bronx 179.269267
2 Queens 162.653526
3 Manhattan 142.876706
4 Brooklyn 130.964910
In [75]:
# Gráfico circular dinámico
import plotly.express as px
px.pie(df_DR, values='days_booked', names='neighbourhood_group', 
       title="Distribución de los días reservados para cada grupo de barrios")
In [76]:
# Gráfico circular estático
import pandas as pd
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 10))
plt.pie(df_DR['days_booked'], labels=df_DR['neighbourhood_group'], autopct='%1.1f%%', startangle=90, 
        colors=['skyblue', 'lightgreen', 'lightcoral', 'lightsalmon'])
plt.title('Distribución de Días Reservados por Grupo de Barrios')
plt.show()

Según la observación del gráfico, en promedio, se destaca que Staten Island es el grupo de barrios con la mayor cantidad de días reservados, mientras que Brooklyn es el grupo con la menor cantidad de días reservados.

Tarea 5b: Visualización de datos (Cualquier herramienta)¶

  • ¿El precio del servicio y el precio de la habitación tienen un impacto mutuo? Ilustre esta relación con un gráfico de dispersión e indique sus inferencias
  • Utilizando un gráfico lineal muestre en qué año tuvo lugar la máxima construcción de habitaciones.

Si utiliza Python para este ejercicio, incluya el código en las celdas siguientes. Si utiliza cualquier otra herramienta, incluya capturas de pantalla de su trabajo.

SOLUCIÓN¶

¿El precio del servicio y el precio de la habitación tienen un impacto mutuo? Ilustre esta relación con un gráfico de dispersión e indique sus inferencias¶

In [77]:
df_Airbnb[['price', 'service_fee']]
Out[77]:
price service_fee
0 966.0 193.0
1 142.0 28.0
2 620.0 124.0
3 368.0 74.0
4 204.0 41.0
... ... ...
102053 696.0 41.0
102054 909.0 41.0
102055 387.0 41.0
102056 848.0 41.0
102057 1128.0 41.0

99146 rows × 2 columns

In [78]:
# Gráfico de dispersión 
import seaborn as sns
plt.figure(figsize=(16,8))
sns.scatterplot(x="service_fee", y="price", data=df_Airbnb)

plt.xlabel('Precio del servicio [$]',fontsize=20)
plt.ylabel('Precio de la habitación [$]',fontsize=20)
plt.title('Relación entre Precio del Servicio y Precio de la Habitación', fontsize=20)
plt.show()

Al observar el gráfico de dispersión, identificamos tres patrones distintos en la relación entre el precio del servicio y el precio de la habitación. En primer lugar, notamos el patrón general de concentración de puntos en una diagonal ascendente, indicando una correlación positiva fuerte entre estas dos variables. Esto sugiere que, en general, cuando el precio del servicio aumenta, también lo hace el precio de la habitación. Además, observamos concentraciones de puntos verticales y horizontales. La concentración de puntos verticales sugiere una relación lineal fuerte, donde el precio de la habitación ejerce una influencia significativa en el precio del servicio. De manera similar, la concentración horizontal indica una fuerte relación lineal, pero en este caso, es el precio del servicio el que afecta principalmente al precio de la habitación. Es importante señalar que la concentración vertical podría sugerir una relación de causalidad, donde cambios en una variable causan cambios en la otra. Para proporcionar más claridad y respaldo a estas observaciones, podríamos examinar ejemplos específicos de valores en el gráfico."

Coeficiente de correlación de Pearson¶


0,00 ---> No existe correlación lineal alguna entre las variables
0,10 ---> Correlación positiva débil
0,50 ---> Correlación positiva media
0,75 ---> Correlación positiva considerable
0,90 ---> Correlación positiva muy fuerte
1,00 ---> Correlación positiva perfecta


In [79]:
# Calcula el coeficiente de correlación de Pearson
correlation = df_Airbnb['service_fee'].corr(df_Airbnb['price'])

print(f"Coeficiente de correlación: {correlation}")
Coeficiente de correlación: 0.9939395285701236

El coeeficiente de correlación de Pearson, muestra que hay una correlación positiva muy fuerte entre el precio del servicio y el precio de la habitación.

Utilizando un gráfico lineal muestre en qué año tuvo lugar la máxima construcción de habitaciones.¶

In [80]:
df_Airbnb.dtypes
Out[80]:
name                               object
host_identity_verified             object
host_name                          object
neighbourhood_group                object
neighbourhood                      object
lat                               float64
long                              float64
instant_bookable                     bool
cancellation_policy                object
room_type                          object
construction_year                 float64
price                             float64
service_fee                       float64
minimum_nights                    float64
number_of_reviews                 float64
last_review                        object
reviews_per_month                 float64
review_rate_number                float64
calculated_host_listings_count    float64
days_booked                       float64
house_rules                        object
license                            object
dtype: object
In [81]:
# Convertir la columna 'construction_year' al tipo de dato 'int64'
df_Airbnb["construction_year"] = df_Airbnb["construction_year"].astype("int64")
In [82]:
df_Airbnb.dtypes
Out[82]:
name                               object
host_identity_verified             object
host_name                          object
neighbourhood_group                object
neighbourhood                      object
lat                               float64
long                              float64
instant_bookable                     bool
cancellation_policy                object
room_type                          object
construction_year                   int64
price                             float64
service_fee                       float64
minimum_nights                    float64
number_of_reviews                 float64
last_review                        object
reviews_per_month                 float64
review_rate_number                float64
calculated_host_listings_count    float64
days_booked                       float64
house_rules                        object
license                            object
dtype: object

Nuevo dataframe para crear gráfico de líneas¶

In [83]:
# Extraer construcción de habitaciones por año
df=df_Airbnb[['construction_year']].value_counts().sort_values(ascending=False).reset_index().rename(columns={0:'habitaciones'})
df
Out[83]:
construction_year habitaciones
0 2012 5160
1 2014 5063
2 2008 5046
3 2006 5030
4 2020 5005
5 2019 5004
6 2009 5000
7 2003 4966
8 2010 4966
9 2022 4960
10 2005 4949
11 2007 4941
12 2015 4928
13 2017 4911
14 2011 4888
15 2018 4883
16 2021 4868
17 2004 4865
18 2016 4858
19 2013 4855
In [84]:
df.dtypes
Out[84]:
construction_year    int64
habitaciones         int64
dtype: object
In [85]:
# Convertir el tipo de dato de la columna'construction_year' a datetime
df['año_construcción']=pd.to_datetime(df["construction_year"],format='%Y')

La función pd.to_datetime se utiliza para convertir la columna 'construction_year' a un objeto de tipo datetime. El argumento format='%Y' especifica el formato del año en el que se encuentran los datos. En este caso, %Y representa un año de cuatro dígitos.

In [86]:
df
Out[86]:
construction_year habitaciones año_construcción
0 2012 5160 2012-01-01
1 2014 5063 2014-01-01
2 2008 5046 2008-01-01
3 2006 5030 2006-01-01
4 2020 5005 2020-01-01
5 2019 5004 2019-01-01
6 2009 5000 2009-01-01
7 2003 4966 2003-01-01
8 2010 4966 2010-01-01
9 2022 4960 2022-01-01
10 2005 4949 2005-01-01
11 2007 4941 2007-01-01
12 2015 4928 2015-01-01
13 2017 4911 2017-01-01
14 2011 4888 2011-01-01
15 2018 4883 2018-01-01
16 2021 4868 2021-01-01
17 2004 4865 2004-01-01
18 2016 4858 2016-01-01
19 2013 4855 2013-01-01
In [87]:
# Encuentra el año con la máxima construcción de habitaciones
año_max_construccion = df.loc[df['habitaciones'].idxmax(), 'año_construcción']

# Gráfico de líneas
df.plot(x='año_construcción', y='habitaciones', figsize=(16, 8), color="green", lw=2, marker='o')

# Añade un marcador en el punto máximo
plt.scatter(año_max_construccion, df['habitaciones'].max(), color='red', label=f'Máximo en {año_max_construccion}')

plt.xlabel('Año', fontsize=20)
plt.ylabel('Construcción de Habitaciones', fontsize=20)
plt.title('Construcción de habitaciones por año', fontsize=20)
plt.legend()
plt.show()

Examinando el gráfico, se observa que el año de mayor construcción de habitaciones fue 2012, marcado por el pico más alto en la línea del gráfico.

Tarea 5c: Visualización de datos (Cualquier herramienta)¶

  • Con la ayuda de gráficos de caja ilustra lo siguiente
  • Efecto del número de tasa de revisión en el precio
  • Efecto de la identidad del host verificada en el precio

Si utiliza Python para este ejercicio, por favor incluya el código en las celdas de abajo. Si utiliza cualquier otra herramienta, por favor incluya capturas de pantalla de su trabajo.

SOLUCIÓN¶

In [88]:
df_Airbnb.columns
Out[88]:
Index(['name', 'host_identity_verified', 'host_name', 'neighbourhood_group',
       'neighbourhood', 'lat', 'long', 'instant_bookable',
       'cancellation_policy', 'room_type', 'construction_year', 'price',
       'service_fee', 'minimum_nights', 'number_of_reviews', 'last_review',
       'reviews_per_month', 'review_rate_number',
       'calculated_host_listings_count', 'days_booked', 'house_rules',
       'license'],
      dtype='object')
In [89]:
# Estandarizamos la columma 'review_rate_number' a un decimal
df_Airbnb['review_rate_number'] = df_Airbnb['review_rate_number'].round(1)

Gráfico de caja para mostrar el efecto del número de tasa de revisión en el precio¶

In [90]:
# Gráfico de caja 1
import matplotlib.pyplot as mplt
import seaborn as sbn

plt.figure(figsize=(15,10))
sbn.boxplot(data=df_Airbnb,x='review_rate_number',y='price')

plt.title('Efecto del Número de Tasas de Revisión en el Precio',fontsize=20)
plt.xlabel('Número de Tasas de Revisión',fontsize=20)
plt.ylabel('Precio',fontsize=20)

plt.show()
In [91]:
#Gráfico de caja dinámico
import plotly.express as px
fig = px.box(df_Airbnb, y="price",x="review_rate_number",)
fig.show()

Al analizar el gráfico, se observa que la mediana permanece constante en general a medida que cambia el número de tasas de revisión, con la excepción de la tasa de revisión de 3.3, donde se observa un cambio notable. La longitud de las cajas no muestra diferencias significativas, salvo para la tasa de revisión de 3.3. Además, se nota una consistencia en la longitud de los bigotes, indicando una baja variabilidad en los datos. No se identifican puntos fuera de los bigotes, lo que sugiere la ausencia de valores atípicos o extremos."

Gráfico de caja para mostrar el efecto de la identidad del host verificada en el precio¶

In [92]:
# Gráfico de caja estático
import matplotlib.pyplot as mplt
import seaborn as sbn

plt.figure(figsize=(15,10))
sbn.boxplot(data=df_Airbnb,x='host_identity_verified',y='price')

plt.title('Efecto de la identidad del host verificado en el Precio',fontsize=20)
plt.xlabel('Identidad del host verificado',fontsize=20)
plt.ylabel('Precio',fontsize=20)
Out[92]:
Text(0, 0.5, 'Precio')
In [93]:
# Gráfico de caja dinámico
import plotly.express as px
fig = px.box(df_Airbnb, y="price",x="host_identity_verified")
fig.show()

No se aprecian cambios notables en la mediana, longitud de los bigotes, longitud y forma de las cajas entre los grupos, indicando que son comparativamente similares. Esto implica que no hay diferencias significativas en términos de ubicación central, dispersión y variabilidad. En otras palabras, los grupos comparten características fundamentales en cuanto a la distribución de los datos.